package com.shiguiwu.springmybatis.javabase.nio.buffer;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @description: 缓冲区
 * @author: stone
 * @date: Created by 2021/11/8 20:32
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.nio.buffer
 */
public class BufferTests {


    public static void main(String[] args) throws Exception {
        //intBuffer();
        //childBuff();

        //onlyReadBuffer();

        //directBuffer();

        directIo();
    }


    /**
     * 创建一个int类型的缓冲区
     */
    public static void intBuffer() {

        IntBuffer intBuffer = IntBuffer.allocate(1024);

        for (int i = 0; i < intBuffer.capacity(); i++) {
            intBuffer.put(i);
        }

        //重置缓冲区
        intBuffer.flip();

        while (intBuffer.hasRemaining()) {
            int i = intBuffer.get();
            System.out.println(i);
        }

    }

    /**
     * 创建子缓冲区
     */
    public static void childBuff() {
        ByteBuffer buffer = ByteBuffer.allocate(10);

        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put((byte) i);
        }

        //创建子缓冲区
        buffer.position(3);
        buffer.limit(7);

        ByteBuffer slice = buffer.slice();

        for (int i = 0; i < slice.capacity(); i++) {
            byte b = slice.get(i);
            b *= 10;
            slice.put(i, b);
        }

        buffer.position(0);
        buffer.limit(buffer.capacity());

        while (buffer.remaining() > 0) {
            System.out.println(buffer.get());
        }

    }

    /**
     * 创建一个只读缓冲区
     */
    public static void onlyReadBuffer() {
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        for (int i = 0; i < byteBuffer.capacity(); i++) {
            byteBuffer.put((byte) i);
        }

        //创建一个只读缓冲区
        ByteBuffer readOnlyBuffer = byteBuffer.asReadOnlyBuffer();


        for (int i = 0; i < byteBuffer.capacity(); i++) {
            byte b = byteBuffer.get(i);
            b *= 2;
            byteBuffer.put(i, b);
        }

        readOnlyBuffer.position(0);
        readOnlyBuffer.limit(byteBuffer.capacity());

        while (readOnlyBuffer.remaining() > 0) {
            System.out.println(readOnlyBuffer.get());
        }

    }

    /**
     * 创建一个直接缓冲区
     * 加快 I/O 速度
     * 要分配直接缓冲区，需要调用 allocateDirect()方法，而不是 allocate()方法，使用方式与普通缓冲区并无区别
     */
    public static void directBuffer() throws Exception {
        FileInputStream fileInputStream = new FileInputStream("E:\\upload\\1.txt");

        FileChannel inputStreamChannel = fileInputStream.getChannel();

        FileOutputStream fileOutputStream = new FileOutputStream("E:\\upload\\2.txt");

        FileChannel outputStreamChannel = fileOutputStream.getChannel();

        //创建直接缓冲区
        ByteBuffer allocateDirect = ByteBuffer.allocateDirect(1024);

        for (; inputStreamChannel.read(allocateDirect)> 0; allocateDirect.clear()) {
            allocateDirect.flip();
            outputStreamChannel.write(allocateDirect);
        }

        System.out.println("end buffer");
    }

    /**
     * 内存映射文件 I/O
     */
    public static void directIo() throws Exception {
        RandomAccessFile file = new RandomAccessFile("E:\\upload\\3.txt", "rw");

        FileChannel channel = file.getChannel();

        MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
        map.put(0, (byte) 45);

        map.put(1023, (byte) 126);

        file.close();
    }
}
